package boardgamer.yavalath.client.replaylobby;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.MotionEvent;
import boardgamer.common.client.ClickableButton;
import boardgamer.common.client.Display;
import boardgamer.common.client.Drawable;
import boardgamer.common.client.HasEventHandler;
import boardgamer.common.client.SimpleButton;
import boardgamer.common.client.layout.BitmapLayout;
import boardgamer.common.client.layout.HasLayout;
import boardgamer.common.client.layout.InvisibleRect;
import boardgamer.common.client.layout.LayoutGroup;
import boardgamer.common.client.layout.TextLayout;
import boardgamer.yavalath.client.pro.ProImageHandler;
import boardgamer.yavalath.client.pro.ProStringHandler;
import boardgamer.yavalath.client.resources.ImageHandler;
import boardgamer.yavalath.common.YavalathReplay;

import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Map;

import static android.graphics.Paint.ANTI_ALIAS_FLAG;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * @author garysoed
 */
public class ReplayFilePicker implements HasLayout, Drawable, HasEventHandler {

  private static final float HORIZONTAL_INSET_RATIO = 0.05f;
  private static final float VERTICAL_INSET_RATIO = 0.25f;

  private final Context context;
  private final PickedHandler pickedHandler;
  private final YavalathReplayLoader replayLoader;
  private final InnerTextLayout innerTextLayout;
  private final ClickableButton innerButton;
  private final ProgressDialog loadingDialog;
  private YavalathReplay pickedReplay;

  public ReplayFilePicker(Context context, PickedHandler pickedHandler) {
    this.context = checkNotNull(context, "context");
    this.pickedHandler = checkNotNull(pickedHandler, "pickedHandler");
    this.replayLoader = new YavalathReplayLoader();

    Paint paint = new Paint(ANTI_ALIAS_FLAG);
    paint.setColorFilter(new LightingColorFilter(Color.RED, 0));

    BitmapLayout background = new BitmapLayout(ProImageHandler.replayFilePicker, paint);
    RectF backgroundRect = background.getBoundingRect();
    RectF textBoundingRect = background.getBoundingRect();
    textBoundingRect.inset(
        backgroundRect.width() * HORIZONTAL_INSET_RATIO,
        backgroundRect.height() * VERTICAL_INSET_RATIO);
    this.innerTextLayout = new InnerTextLayout(textBoundingRect);
    
    this.innerButton = new ClickableButton(
        new SimpleButton(
            new InnerButton(innerTextLayout, background),
            new EventHandler() {
              @Override
              public void onEvent(float eventX, float eventY, int eventAction) {
                if (eventAction == MotionEvent.ACTION_UP) {
                  pickFile();
                }
              }
            },
            background.getBoundingRect()),
        new BitmapLayout(ProImageHandler.replayFilePickerGlow, paint));
    this.loadingDialog = ProgressDialog.show(context, "Loading", "Loading files ...");
    this.loadingDialog.hide();
  }

  public void pickFile() {
    loadingDialog.show();
    replayLoader.load(new YavalathReplayLoader.LoadReplayCallback() {
      @Override
      public void loadComplete(final Map<String, YavalathReplay> replays) {
        final String[] items = replays.keySet().toArray(new String[replays.size()]);
        Arrays.sort(items);
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
        dialogBuilder.setTitle(ProStringHandler.instance().replayLobbyDialogTitle);
        dialogBuilder.setItems(items,
            new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialogInterface, int i) {
                String fileName = items[i];
                pickedReplay = replays.get(fileName);
                innerTextLayout.setText(fileName);
                pickedHandler.onReplayPicked(pickedReplay);
              }
            });
        loadingDialog.hide();
        dialogBuilder.create().show();
      }
    });
  }

  @Nullable public YavalathReplay getPickedReplay() {
    return pickedReplay;
  }

  @Override
  public void draw(Canvas canvas) {
    innerButton.draw(canvas);
  }

  @Override
  public void handleEvent(float eventX, float eventY, int eventAction) {
    innerButton.handleEvent(eventX, eventY, eventAction);
  }

  @Override
  public RectF getCollisionBox() {
    return innerButton.getCollisionBox();
  }

  @Override
  public void setBoundingRect(RectF boundingRect) {
    innerButton.setBoundingRect(boundingRect);
  }

  @Override
  public RectF getBoundingRect() {
    return innerButton.getBoundingRect();
  }

  private static class InnerButton implements Display {

    private final InnerTextLayout innerTextLayout;
    private final BitmapLayout background;
    private final LayoutGroup group;
    
    public InnerButton(InnerTextLayout innerTextLayout, BitmapLayout background) {
      this.innerTextLayout = checkNotNull(innerTextLayout, "innerTextLayout");
      this.background = checkNotNull(background, "background");
      this.group = new LayoutGroup()
          .add(background).atCurrentRect()
          .add(innerTextLayout).atCurrentRect()
          .horizontalAlign(LayoutGroup.HorizontalAlign.CENTER)
          .verticalAlign(LayoutGroup.VerticalAlign.CENTER);
    }

    @Override
    public void draw(Canvas canvas) {
      background.draw(canvas);
      innerTextLayout.draw(canvas);
    }

    @Override
    public void setBoundingRect(RectF boundingRect) {
      group.setBoundingRect(boundingRect);
    }

    @Override
    public RectF getBoundingRect() {
      return group.getBoundingRect();
    }
  }

  private static class InnerTextLayout implements Drawable, HasLayout {

    private final Paint textPaint;
    private final InvisibleRect textBoundingRect;
    private TextLayout textLayout;
    private LayoutGroup group;

    public InnerTextLayout(RectF textBoundingRect) {
      this.textPaint = new Paint(ANTI_ALIAS_FLAG);
      this.textPaint.setTypeface(ImageHandler.headingFont);
      this.textPaint.setTextSize(30f);
      this.textBoundingRect = new InvisibleRect(textBoundingRect);
      setText(ProStringHandler.instance().replayLobbyPickFile);
    }
    
    public void setText(String text) {
      textLayout = new TextLayout(text, new Paint(textPaint));
      textLayout.setBoundingRect(textBoundingRect.getBoundingRect());
      group = new LayoutGroup()
          .add(textLayout).atCurrentRect()
          .add(textBoundingRect).atCurrentRect();
    }

    @Override
    public void draw(Canvas canvas) {
      if (textLayout != null) {
        textLayout.draw(canvas);
      }
    }

    @Override
    public void setBoundingRect(RectF boundingRect) {
      group.setBoundingRect(boundingRect);
    }

    @Override
    public RectF getBoundingRect() {
      return group.getBoundingRect();
    }
  }

  public interface PickedHandler {
    
    void onReplayPicked(YavalathReplay replay);
  }
}
